﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace HYRevitCode.ParameterEditUtility
{
	public class SharedParameterEditor
	{
        public static bool CreateSharedParams(UIApplication inputApp, string strShareParameterPath, string parameterName, string parameterGroup, List<BuiltInCategory> lstBlindingCategory, bool bIfTypeBinding = true, BuiltInParameterGroup inputParameterGroup = BuiltInParameterGroup.INVALID)
		{
			if (string.IsNullOrWhiteSpace(strShareParameterPath))
			{
				return false;
			}
			SharedParameterEditor.m_SharedParamsPath = strShareParameterPath;
			Application application = inputApp.Application;
			Document document = inputApp.ActiveUIDocument.Document;
			string sharedParametersFilename = application.SharedParametersFilename;
            Definition orCreateSharedParamsDefinition = SharedParameterEditor.GetOrCreateSharedParamsDefinition(SharedParameterEditor.GetOrCreateSharedParamsGroup(SharedParameterEditor.GetSharedParamsFile(application), parameterGroup), (ParameterType)1, parameterName);
			bool result = SharedParameterEditor.BindCategoryToShareParam(application, document, lstBlindingCategory, bIfTypeBinding, orCreateSharedParamsDefinition, inputParameterGroup);
			if (sharedParametersFilename != null)
			{
				application.SharedParametersFilename = sharedParametersFilename;
			}
			return result;
		}

        private static bool BindCategoryToShareParam(Autodesk.Revit.ApplicationServices.Application inputApp, Autodesk.Revit.DB.Document inputDoc, List<BuiltInCategory> lstBlindingCategory, bool bIfTypeBinding, Definition fireRatingParamDef, BuiltInParameterGroup inputParameterGroup = BuiltInParameterGroup.INVALID)
		{
			CategorySet categorySet = inputApp.Create.NewCategorySet();
			foreach (BuiltInCategory builtInCategory in lstBlindingCategory)
			{
				Category category = inputDoc.Settings.Categories.get_Item(builtInCategory);
				try
				{
					categorySet.Insert(category);
				}
				catch (Exception)
				{
				}
			}
			bool result;
			try
			{
				Binding binding;
				if (bIfTypeBinding)
				{
					binding = inputApp.Create.NewTypeBinding(categorySet);
				}
				else
				{
					binding = inputApp.Create.NewInstanceBinding(categorySet);
				}
				result = inputDoc.ParameterBindings.Insert(fireRatingParamDef, binding, inputParameterGroup);
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private static DefinitionFile GetSharedParamsFile(Autodesk.Revit.ApplicationServices.Application app)
		{
			app.SharedParametersFilename = SharedParameterEditor.m_SharedParamsPath;
			DefinitionFile result;
			try
			{
				result = app.OpenSharedParameterFile();
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		private static DefinitionGroup GetOrCreateSharedParamsGroup(DefinitionFile sharedParametersFile, string groupName)
		{
			DefinitionGroup definitionGroup = sharedParametersFile.Groups.get_Item(groupName);
			if (definitionGroup == null)
			{
				try
				{
					definitionGroup = sharedParametersFile.Groups.Create(groupName);
				}
				catch (Exception)
				{
					definitionGroup = null;
				}
			}
			return definitionGroup;
		}

		private static Definition GetOrCreateSharedParamsDefinition(DefinitionGroup defGroup, ParameterType defType, string defName)
		{
			Definition definition = defGroup.Definitions.get_Item(defName);
			if (definition == null)
			{
				try
				{
					ExternalDefinitionCreationOptions externalDefinitionCreationOptions = new ExternalDefinitionCreationOptions(defName, defType);
					externalDefinitionCreationOptions.Visible = true;
					definition = defGroup.Definitions.Create(externalDefinitionCreationOptions);
				}
				catch (Exception)
				{
					definition = null;
				}
			}
			return definition;
		}

		private static string m_SharedParamsPath;
	}
}
